package com.bluesky.jwf.component;

import java.io.IOException;
import java.io.Serializable;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

import com.bluesky.common.TreeNode;
import com.bluesky.javawebbrowser.domain.html.HtmlPage;
import com.bluesky.javawebbrowser.domain.html.tags.Tag;
import com.bluesky.javawebbrowser.domain.html.tags.TagType;
import com.bluesky.jwf.component.event.EventHandler;
import com.bluesky.jwf.controller.Controller;

/**
 * component optionally can be loaded from *.html resource file
 * 
 * @author hz00260
 * 
 */
public class Component extends Tag implements Serializable {

	/**
	 * store event handlers, the sub class's responsibility is put event names.
	 */
	protected Map<String, EventHandler> eventHandlers;
	protected Controller<Object, Component> controller;

	protected boolean visible = true;

	public Component() {
		super(TagType.COMPONENT);

		eventHandlers = new HashMap<String, EventHandler>();
	}

	/**
	 * the container tag, which can be either div or tr td, or whatever
	 */
	// protected Tag rootTag;
	/**
	 * load from html segment resource file
	 * 
	 * @param html
	 */
	public void init(String html) {
		HtmlPage page = new HtmlPage(html, true);

		Tag rootTag = (Tag) page.getRoot();

		for (TreeNode tn : rootTag.getChildren())
			addChild(tn);

		/**
		 * if there is only one top child tag, and its jwfclass value is like
		 * 'a>b' then it is a multiple class tag. we should remove the first
		 * class since it is for outside component.
		 */
		if (getChildren().size() == 1) {

			Tag t = (Tag) getChildren().get(0);

			if (t.containsAttribute(JWF_CLASS)) {
				String jwfclass = t.getAttribute(JWF_CLASS);
				if (jwfclass.contains(",")) {
					String[] classes = jwfclass.split(",");
					// "a>".split()'s return value's length is 1;
					if (classes.length > 1)
						t.setAttribute(JWF_CLASS, classes[1]);
					else
						t.removeAttribute(JWF_CLASS);
				}

			}

		}

	}

	@Override
	public void writeHtml(Writer writer) throws IOException {

		if (!visible)
			return;

		/**
		 * do not render itself
		 */
		for (TreeNode tn : getChildren()) {
			Tag t = (Tag) tn;
			t.writeHtml(writer);
		}
	}

	@Override
	public String toHtml() {
		/**
		 * the root tag itself won't be output
		 */
		StringBuilder sb = new StringBuilder();
		for (TreeNode n : getChildren()) {
			Tag tag = (Tag) n;
			sb.append(tag.toHtml());
		}
		return sb.toString();
	}

	/**
	 * process the submitted values from browser.
	 * 
	 * @param params
	 */
	public void setPostBackData(String name, String value) {
		// intend to be empty
	}

	public void handleEvent(String eventName) {
		if (getController() != null) {
			getController().handleEvent(eventName);
		} else if (eventHandlers.containsKey(eventName)) {
			EventHandler handler = eventHandlers.get(eventName);
			if (handler != null)
				handler.handle(this, null, null);
		}
	}

	/**
	 * a component may has additional java script.
	 * 
	 * @return
	 */
	public Tag getScript() {
		return null;
	}

	/**
	 * an event between loadPostBackData and executePostBackEvent.
	 */
	public void load() {

	}

	public Controller getController() {
		return controller;
	}

	public void setController(Controller controller) {
		this.controller = controller;
		controller.setView(this);
	}

	public static void main(String[] args) {
		String s = ",a";
		String[] ss = s.split(",");
		System.out.println(ss.length);
	}

	public boolean isVisible() {
		return visible;
	}

	public void setVisible(boolean visible) {
		this.visible = visible;
	}

}
